package com.ceuer.demo.juc.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 单例模式-DCL 懒汉式
 */
public class LazyMan3 {
	private LazyMan3(){
		System.out.println(Thread.currentThread().getName()+"\t ok");
	}
	
	//最终还需要在此强调式添加volatile保证其原子性唯一
	private volatile static LazyMan3 lazyMan3;
	
	//双重检测锁模式的 懒汉式单例 DCL懒汉式
	//双重检测 if(LAZYMAN2 ==null) 有两次
	//锁 synchronized (LazyMan2.class)
	public static LazyMan3 getInstance(){
		if(lazyMan3 ==null){
			synchronized (LazyMan3.class){//同步锁class保证只有一个类同时在用
				if(lazyMan3 ==null){
					lazyMan3 =new LazyMan3();//虽然 不是一个原子性操作
				}
			}
		}
		return lazyMan3;
	}
	
	public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
		/*for (int i = 0; i < 10; i++) {
			new Thread(()->{
				LazyMan3.getInstance();
			}).start();
		}*/
		
		//反射测试
		LazyMan3 instance1 = LazyMan3.getInstance();
		
		Constructor<LazyMan3> declaredConstructor = LazyMan3.class.getDeclaredConstructor(null);
		declaredConstructor.setAccessible(true);//无视私有构造方法
		LazyMan3 instance2 =declaredConstructor.newInstance();
		System.out.println(instance1);
		System.out.println(instance2);
		/*
			com.ceuer.demo.juc.single.LazyMan3@61bbe9ba
			com.ceuer.demo.juc.single.LazyMan3@610455d6
			已经不是一个单例的实例了
		 */
	}
	
}
